// 底层内存管理
#ifndef MY_NEW_H_
#define MY_NEW_H_
#include <exception/spw_exception.h>
#include <spw_config.h>

namespace spwstd {
namespace spwexcept {
/* 异常, 内存分配异常 */
// BadAlloc, 内存分配失败
class BadAlloc : public Exception {
public:
    BadAlloc() noexcept {};
    virtual ~BadAlloc() noexcept {};
    virtual const char* What() const noexcept{ return "spwstd::spwexcept::BadAlloc"; };
};

// bad_array_new_lenght, 分配非法长度数组
class BadArrayNewLenght : public BadAlloc {
public:
    BadArrayNewLenght() noexcept {};
    virtual ~BadArrayNewLenght() noexcept {};
    virtual const char* What() const noexcept{ return "spwstd::spwexcept::BadArrayNewLenght"; };
};
} // namespace spwexcept

/* new 处理函数的函数指针 */
using NewHandler = void (*)();
NewHandler setNewHandler(NewHandler) noexcept;
NewHandler getNewHandler() noexcept;

// 用户可以通过nothrow，调用非抛出异常版本
struct Nothrow_t {};
extern const Nothrow_t nothrow; 

} //namespace spwstd

/* 标准的new和delete */
// operator new delete不能定义在namespace中
// 只能定以在类中或全局
// 抛出异常版本
void *operator new(spwconfig::size_t);
void *operator new[](spwconfig::size_t);
void operator delete(void*) noexcept;
void operator delete[](void*) noexcept;
// 不会抛出异常版本
void *operator new(spwconfig::size_t, const spwstd::Nothrow_t&) noexcept;
void *operator new[](spwconfig::size_t, const spwstd::Nothrow_t&) noexcept;
void operator delete(void*, const spwstd::Nothrow_t&) noexcept;
void operator delete[](void*, const spwstd::Nothrow_t&) noexcept;

// placement new
//无法替换，stl<new>中直接定义，link时无法替换自己的定义
//inline void *operator new(spwconfig::size_t, void* ptr) noexcept { return ptr; }
//inline void *operator new[](spwconfig::size_t, void* ptr) noexcept{ return ptr; }
//inline void operator delete(void*, void*) noexcept {};
//inline void operator delete[](void*, void*) noexcept {};

#endif //MY_NEW_H_
